#pragma once

#include <cstdint>

#include "graphic/Drawer.h"

//////////////////////////////////////////////////////////////////////////
//
// Struct that represents a background with vertical scrolling capability
//
// You should initialize it with an array of textures, each one of the
// same size.
//
// Texture height = N * window height
// Texture width = window width
//
// To get good results in ENDLESS mode:
// The first WINDOW_HEIGHT pixels of a texture should be the same
// that the last WINDOW_HEIGHT pixels of its previous texture.
// The last WINDOW_HEIGHT pixels of a texture should be the same
// that the first WINDOW_HEIGHT pixels of its next texture.
//
// It can be automatically scrolled at certain speed per frame
// or manually scrolled
//
// It can be scrolled in up or down directions
//
// It has an endless mode, i.e., a circular scrolling background
//
//////////////////////////////////////////////////////////////////////////

struct SDL_Texture;

enum class VScrollDirection {
    UP,
    DOWN
};

struct VScrollableBackground {
    // Used to draw
    TextureData mTexData;

    // Textures that compose the entire background
    SDL_Texture* * const mTextures;
    const size_t mNumTex;

    // Scrolling direction
    VScrollDirection mDir;

    // Cache background height, i.e., sum
    // of all textures heights
    uint32_t mBackgroundH;

    // Cache texture height
    uint32_t mTexHeight;

    // Current y coordinate where we need to 
    // position the entire texture (concatenation of all texture)
    // to be drawn
    int mCurY;

    // Scrolling speed in Y axis a per frame basis
    int mSpeed;

    // Circular (endless) scrolling
    bool mEndless;

    VScrollableBackground(SDL_Texture* * const tex,
                          const size_t numTex,
                          const uint32_t speed, 
                          const VScrollDirection dir,
                          const bool endless);
};

// Reset background position to the initial one
// according scrolling direction
void reset(VScrollableBackground& background);

void changeSpeed(const uint32_t speed, VScrollableBackground& background);

// Change direction. If new direction is NONE, 
// speed will be set to zero
void changeDirection(const VScrollDirection dir, VScrollableBackground& background);

void setEndless(const bool b, VScrollableBackground& background);

// Update current background position based on
// direction and speed.
// This should be called once per frame.
void update(VScrollableBackground& background);

// Update current background position based on
// a new speed.
// This ignores background speed and direction
// previously set.
// This should be called once per frame.
void update(const int speed, VScrollableBackground& background);